<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>Spring5框架 | 无人深空</title><meta name="keywords" content="Spring"><meta name="author" content="zcm"><meta name="copyright" content="zcm"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="Spring5 框架课程内容 Spring 框架概述 IOC 容器  IOC 底层原理 IOC 接口（BeanFactory） IOC 操作 Bean 管理（基于 xml） IOC 操作 Bean 管理（基于注解）   Aop JdbcTemplate 事务管理 Spring5 新特性  Spring5 框架概述 Spring 是轻量级的开源的 JavaEE 框架  Spring 可以解决企业应用">
<meta property="og:type" content="article">
<meta property="og:title" content="Spring5框架">
<meta property="og:url" content="https://gitee.com/zcmmmm/zcmmmm/2022/09/23/Spring5%E6%A1%86%E6%9E%B6/index.html">
<meta property="og:site_name" content="无人深空">
<meta property="og:description" content="Spring5 框架课程内容 Spring 框架概述 IOC 容器  IOC 底层原理 IOC 接口（BeanFactory） IOC 操作 Bean 管理（基于 xml） IOC 操作 Bean 管理（基于注解）   Aop JdbcTemplate 事务管理 Spring5 新特性  Spring5 框架概述 Spring 是轻量级的开源的 JavaEE 框架  Spring 可以解决企业应用">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/Spring/Spring.jpg">
<meta property="article:published_time" content="2022-09-23T03:46:30.000Z">
<meta property="article:modified_time" content="2022-09-23T03:48:04.090Z">
<meta property="article:author" content="zcm">
<meta property="article:tag" content="Spring">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/Spring/Spring.jpg"><link rel="shortcut icon" href="/img/favicon.png"><link rel="canonical" href="https://gitee.com/zcmmmm/zcmmmm/2022/09/23/Spring5%E6%A1%86%E6%9E%B6/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"/search.xml","preload":false,"languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":200},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: {"chs_to_cht":"你已切换为繁体","cht_to_chs":"你已切换为简体","day_to_night":"你已切换为深色模式","night_to_day":"你已切换为浅色模式","bgLight":"#49b1f5","bgDark":"#1f1f1f","position":"bottom-left"},
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'Spring5框架',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2022-09-23 11:48:04'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><link rel="stylesheet" href="/css/categories.css?v1"><link rel="stylesheet" href="/css/navigation.css?v1"><link rel="stylesheet" href="/css/custom.css?v1"><meta name="generator" content="Hexo 6.3.0"></head><body><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="https://s2.loli.net/2022/09/22/36LN4kcjYOd9HT8.jpg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">43</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">25</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">11</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="not-top-img" id="page-header"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">无人深空</a></span><div id="menus"></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div></div><div id="nav-right"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i></a></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav></header><main class="layout" id="content-inner"><div id="post"><div id="post-info"><h1 class="post-title">Spring5框架</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2022-09-23T03:46:30.000Z" title="发表于 2022-09-23 11:46:30">2022-09-23</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2022-09-23T03:48:04.090Z" title="更新于 2022-09-23 11:48:04">2022-09-23</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/Spring/">Spring</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">10.1k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>43分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="Spring5框架"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div><article class="post-content" id="article-container"><h2 id="Spring5-框架"><a href="#Spring5-框架" class="headerlink" title="Spring5 框架"></a><a target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV1Vf4y127N5">Spring5 框架</a></h2><h3 id="课程内容"><a href="#课程内容" class="headerlink" title="课程内容"></a>课程内容</h3><ul>
<li>Spring 框架概述</li>
<li>IOC 容器 <ul>
<li>IOC 底层原理</li>
<li>IOC 接口（BeanFactory）</li>
<li>IOC 操作 Bean 管理（基于 xml）</li>
<li>IOC 操作 Bean 管理（基于注解）</li>
</ul>
</li>
<li>Aop</li>
<li>JdbcTemplate</li>
<li>事务管理</li>
<li>Spring5 新特性</li>
</ul>
<h3 id="Spring5-框架概述"><a href="#Spring5-框架概述" class="headerlink" title="Spring5 框架概述"></a>Spring5 框架概述</h3><ul>
<li><p>Spring 是轻量级的开源的 JavaEE 框架</p>
</li>
<li><p>Spring 可以解决企业应用开发的复杂性</p>
</li>
<li><p>Spring 有两个核心部分：<strong>IOC 和 Aop</strong> </p>
<ul>
<li><strong>IOC：控制反转，把创建对象过程交给 Spring 进行管理</strong></li>
<li><strong>Aop：面向切面，不修改源代码进行功能增强</strong></li>
</ul>
</li>
<li><p>Spring 特点</p>
<ul>
<li>方便解耦，简化开发</li>
<li>Aop 编程支持</li>
<li>方便程序测试</li>
<li>方便和其他框架进行整合</li>
<li>方便进行事务操作</li>
<li>降低 API 开发难度</li>
</ul>
</li>
<li><p>Spring 入门</p>
<ol>
<li><p>下载 Spring5 相关资源</p>
</li>
<li><p>创建 Java 工程，导入 Spring5 基本 jar 包</p>
</li>
<li><p>创建普通类</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">User</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;add......&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>创建 Spring 配置文件，在配置文件中配置创建的对象</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--配置User对象创建--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;user&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.User&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>测试</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testAdd</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="comment">// 1.加载xml配置文件</span></span><br><span class="line">    <span class="type">ApplicationContext</span> <span class="variable">context</span> <span class="operator">=</span></span><br><span class="line">        <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;bean1.xml&quot;</span>);</span><br><span class="line">    <span class="comment">// 2.获取配置对象</span></span><br><span class="line">    <span class="type">User</span> <span class="variable">user</span> <span class="operator">=</span> context.getBean(<span class="string">&quot;user&quot;</span>, User.class);</span><br><span class="line"></span><br><span class="line">    System.out.println(user);</span><br><span class="line">    user.add();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
</ol>
</li>
</ul>
<h3 id="IOC-容器"><a href="#IOC-容器" class="headerlink" title="IOC 容器"></a>IOC 容器</h3><ul>
<li><p>IOC 基本介绍</p>
<ul>
<li>控制反转，把对象创建和对象之间的调用过程，交给 Spring 进行管理</li>
<li>使用 IOC 目的：<strong>为了耦合度降低</strong></li>
<li>做入门案例就是 IOC 实现</li>
</ul>
</li>
<li><p>IOC 底层原理：<strong>xml 解析 + 工厂模式 + 反射</strong></p>
<ul>
<li><p>原始实现： <code>UserService</code> 与 <code>UserDao</code> 高度耦合</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">UserDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;add......&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">execute</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">UserDao</span> <span class="variable">dao</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">UserDao</span>();</span><br><span class="line">        dao.add();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>改进1：工厂模式降低 <code>UserService</code> 与 <code>UserDao</code> 之间的耦合度</p>
<p>但是 <code>UserService</code> 与 <code>UserFactory</code> 有一定耦合</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">UserDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;add......&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">UserFactory</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> UserDao <span class="title function_">getDao</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">UserDao</span>();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">execute</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">UserDao</span> <span class="variable">dao</span> <span class="operator">=</span> UserFactory.getDao();</span><br><span class="line">        dao.add();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>改进2：IOC （xml 解析 + 反射 + 工厂类）</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">UserDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;add......&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">UserFactory</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> UserDao <span class="title function_">getDao</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="comment">// 1.通过 xml 解析获取 Class 属性值</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">classValue</span> <span class="operator">=</span> <span class="string">&quot;com.atguigu.spring5.User&quot;</span>(class属性值);</span><br><span class="line">        <span class="comment">// 2.通过反射创建对象</span></span><br><span class="line">        <span class="type">Class</span> <span class="variable">clazz</span> <span class="operator">=</span> Class.forName(classValue);</span><br><span class="line">        <span class="keyword">return</span> (UserDao)clazz.newInstance();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line">    UserDao dao;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">execute</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">UserDao</span> <span class="variable">dao</span> <span class="operator">=</span> UserFactory.getDao();</span><br><span class="line">        dao.add();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--xml 配置文件--&gt;</span></span><br><span class="line"><span class="comment">&lt;!--配置User对象创建--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;user&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.User&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>IOC（BeanFactory 接口）</p>
<ul>
<li><p>IOC 思想基于 IOC 容器完成，IOC 容器底层就是<strong>对象工厂</strong></p>
</li>
<li><p>Spring 提供 IOC 容器实现两种方式：（两个接口）</p>
<ul>
<li><p>**<code>BeanFactory</code>**：IOC 容器基本实现，是 Spring 内部的使用接口，不提供开发人员进行使用</p>
<p><strong>加载配置文件时候不会创建对象，在获取对象（使用）才去创建对象</strong></p>
</li>
<li><p><strong><code>ApplicationContext</code><strong>：BeanFactory 接口的子接口，提供更多更强大的功能，一般由开发人员进行使用</strong>（常用）</strong></p>
<p><strong>加载配置文件时候就会把在配置文件对象进行创建</strong></p>
</li>
</ul>
</li>
<li><p><code>ApplicationContext</code> 接口主要实现类</p>
<p><a target="_blank" rel="noopener" href="https://imgtu.com/i/qS5cZj"><img src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/Spring/qS5cZj.md.png" alt="qS5cZj.md.png"></a></p>
</li>
</ul>
</li>
<li><p>IOC 操作 Bean 管理（概念）</p>
<ul>
<li><p>什么是 Bean 管理</p>
<ul>
<li>Spring <strong>创建对象</strong></li>
<li>Spirng <strong>注入属性</strong></li>
</ul>
</li>
<li><p>Bean 管理操作的两种方式</p>
<ul>
<li><p>基于 xml 配置文件方式实现</p>
</li>
<li><p>基于注解方式实现</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>基于 xml 配置文件方式实现 Bean 管理</strong></p>
<ol>
<li><p>基于 xml 方式创建对象</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">&lt;bean id=&quot;user&quot;, class=&quot;com.atguigu.spring5.User&quot;&gt;&lt;/bean&gt;</span><br></pre></td></tr></table></figure>

<ul>
<li>在 spring 配置文件中，使用 bean 标签，标签里面添加对应属性，就可以实现对象创建 </li>
<li>在 bean 标签有很多属性，介绍常用的属性<ul>
<li>id 属性：唯一标识</li>
<li>class 属性：类全路径（包类路径）</li>
</ul>
</li>
<li>创建对象时候，默认也是执行<strong>无参数构造方法</strong>完成对象创建</li>
</ul>
</li>
<li><p>基于 xml 方式注入属性</p>
<ul>
<li><p>DI：依赖注入（IOC 的一种实现方式），即注入属性</p>
</li>
<li><p>注入方式1-使用 <code>setter 方法</code> 进行注入</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Book</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> String bname;</span><br><span class="line">    <span class="keyword">private</span> String bauthor;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setBname</span><span class="params">(String bname)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.bname = bname;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setBauthor</span><span class="params">(String bauthor)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.bauthor = bauthor;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;book&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.Book&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;bname&quot;</span> <span class="attr">value</span>=<span class="string">&quot;水浒传&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;bauthor&quot;</span> <span class="attr">value</span>=<span class="string">&quot;施耐庵&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>注入方式2-使用有参构造进行注入</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Orders</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> String oname;</span><br><span class="line">    <span class="keyword">private</span> String address;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Orders</span><span class="params">(String oname,String address)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.oname = oname;</span><br><span class="line">        <span class="built_in">this</span>.address = address;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;orders&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.Orders&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">&quot;oname&quot;</span> <span class="attr">value</span>=<span class="string">&quot;电脑&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">constructor-arg</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">&quot;address&quot;</span> <span class="attr">value</span>=<span class="string">&quot;China&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">constructor-arg</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>p 名称空间注入（了解即可）</p>
<p>使用 p 名称空间注入，可以简化基于 xml 配置方式</p>
<ol>
<li><p>添加 p 名称空间在配置文件中</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:p</span>=<span class="string">&quot;http://www.springframework.org/schema/p&quot;</span></span></span><br></pre></td></tr></table></figure>
</li>
<li><p>进行属性注入，在 bean 标签里面进行操作</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;book&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.Book&quot;</span> <span class="attr">p:bname</span>=<span class="string">&quot;水浒传&quot;</span> <span class="attr">p:bauthor</span>=<span class="string">&quot;施耐庵&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
</ol>
</li>
</ul>
</li>
<li><p>xml 注入其他类型属性</p>
<ul>
<li><p>字面量</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--设置null--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;book&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.Book&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;bname&quot;</span> <span class="attr">value</span>=<span class="string">&quot;水浒传&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;bauthor&quot;</span>&gt;</span></span><br><span class="line">    	<span class="tag">&lt;<span class="name">null</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--含特殊符号--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;book&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.Book&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;bname&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>&lt;![CDATA[&lt;&lt;水浒传&gt;&gt;]]]&gt;<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;bauthor&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">null</span>&gt;</span><span class="tag">&lt;/<span class="name">null</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>注入属性 - 外部 bean</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line">    <span class="comment">//创建 UserDao 类型属性，生成 set 方法</span></span><br><span class="line">    <span class="keyword">private</span> UserDao userDao;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setUserDao</span><span class="params">(UserDao userDao)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.userDao = userDao;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;service add...............&quot;</span>);</span><br><span class="line">        userDao.update();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userDaoImpl&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.dao.UserDaoImpl&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;userService&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.service.UserService&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--注入 userDao 对象--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;userDao&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;userDaoImpl&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>注入属性 - 内部 bean</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//部门类</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Dept</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> String dname;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setDname</span><span class="params">(String dname)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.dname = dname;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//员工类</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Emp</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> String ename;</span><br><span class="line">    <span class="keyword">private</span> String gender;</span><br><span class="line">    <span class="comment">//员工属于某一个部门，使用对象形式表示</span></span><br><span class="line">    <span class="keyword">private</span> Dept dept;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setDept</span><span class="params">(Dept dept)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.dept = dept;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setEname</span><span class="params">(String ename)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.ename = ename;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setGender</span><span class="params">(String gender)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.gender = gender;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;emp&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.bean.Emp&quot;</span>&gt;</span></span><br><span class="line">     <span class="comment">&lt;!--设置两个普通属性--&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;ename&quot;</span> <span class="attr">value</span>=<span class="string">&quot;lucy&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;gender&quot;</span> <span class="attr">value</span>=<span class="string">&quot;女&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">     <span class="comment">&lt;!--设置对象类型属性--&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;dept&quot;</span>&gt;</span></span><br><span class="line"> 		<span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;dept&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.bean.Dept&quot;</span>&gt;</span></span><br><span class="line"> 			<span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;dname&quot;</span> <span class="attr">value</span>=<span class="string">&quot;安保部&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"> 		<span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"> 	<span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>注入属性 - 级联 bean</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--级联赋值 方法1--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;emp&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.bean.Emp&quot;</span>&gt;</span></span><br><span class="line">     <span class="comment">&lt;!--设置两个普通属性--&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;ename&quot;</span> <span class="attr">value</span>=<span class="string">&quot;lucy&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;gender&quot;</span> <span class="attr">value</span>=<span class="string">&quot;女&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">     <span class="comment">&lt;!--级联赋值--&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;dept&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;dept&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;dept&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.bean.Dept&quot;</span>&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;dname&quot;</span> <span class="attr">value</span>=<span class="string">&quot;财务部&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--级联赋值 方法2--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;emp&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.bean.Emp&quot;</span>&gt;</span></span><br><span class="line">     <span class="comment">&lt;!--设置两个普通属性--&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;ename&quot;</span> <span class="attr">value</span>=<span class="string">&quot;lucy&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;gender&quot;</span> <span class="attr">value</span>=<span class="string">&quot;女&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">     <span class="comment">&lt;!--级联赋值--&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;dept&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;dept&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">     <span class="comment">&lt;!--需有 dname 的 getter 方法--&gt;</span></span><br><span class="line">     <span class="comment">&lt;!--最终结果为技术部--&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;dept.dname&quot;</span> <span class="attr">value</span>=<span class="string">&quot;技术部&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;dept&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.bean.Dept&quot;</span>&gt;</span></span><br><span class="line"> 	<span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;dname&quot;</span> <span class="attr">value</span>=<span class="string">&quot;财务部&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>xml 注入集合属性</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Stu</span> &#123;</span><br><span class="line">    <span class="comment">// 1.数组类型属性</span></span><br><span class="line">    <span class="keyword">private</span> String[] courses;</span><br><span class="line">    <span class="comment">// 2.list 集合类型属性</span></span><br><span class="line">    <span class="keyword">private</span> List&lt;String&gt; list;</span><br><span class="line">    <span class="comment">// 3.map 集合类型属性</span></span><br><span class="line">    <span class="keyword">private</span> Map&lt;String,String&gt; maps;</span><br><span class="line">    <span class="comment">// 4.set 集合类型属性</span></span><br><span class="line">    <span class="keyword">private</span> Set&lt;String&gt; sets;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setSets</span><span class="params">(Set&lt;String&gt; sets)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.sets = sets;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setCourses</span><span class="params">(String[] courses)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.courses = courses;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setList</span><span class="params">(List&lt;String&gt; list)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.list = list;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setMaps</span><span class="params">(Map&lt;String, String&gt; maps)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.maps = maps;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li>注入数组类型属性</li>
<li>注入 List 集合类型属性</li>
<li>注入 Map 集合类型属性</li>
</ul>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;stu&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.collectiontype.Stu&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--数组类型属性注入--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;courses&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">array</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span>java 课程<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span>数据库课程<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">array</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--list 类型属性注入--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;list&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">list</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span>张三<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span>小三<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">list</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--map 类型属性注入--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;maps&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">map</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key</span>=<span class="string">&quot;JAVA&quot;</span> <span class="attr">value</span>=<span class="string">&quot;java&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">entry</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key</span>=<span class="string">&quot;PHP&quot;</span> <span class="attr">value</span>=<span class="string">&quot;php&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">entry</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">map</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--set 类型属性注入--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;sets&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">set</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span>MySQL<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span>Redis<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">set</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>

<ul>
<li><p>集合注入的细节问题</p>
<ul>
<li><p>集合中保存对象类型</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--创建多个 course 对象--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;course1&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.collectiontype.Course&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;cname&quot;</span> <span class="attr">value</span>=<span class="string">&quot;Spring5 框架&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;course2&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.collectiontype.Course&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;cname&quot;</span> <span class="attr">value</span>=<span class="string">&quot;MyBatis 框架&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!--注入 list 集合类型，值是对象--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;courseList&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">list</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">ref</span> <span class="attr">bean</span>=<span class="string">&quot;course1&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">ref</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">ref</span> <span class="attr">bean</span>=<span class="string">&quot;course2&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">ref</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">list</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>提取集合注入部分，便于复用</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:util</span>=<span class="string">&quot;http://www.springframework.org/schema/util&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--1 提取 list 集合类型属性注入--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">util:list</span> <span class="attr">id</span>=<span class="string">&quot;bookList&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>易筋经<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>九阴真经<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>九阳神功<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">util:list</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--2 提取 list 集合类型属性注入使用--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;book&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.collectiontype.Book&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;list&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;bookList&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><p>IOC 操作 Bean 管理（FactoryBean）</p>
<ul>
<li><p>Spring 有两种类型 bean，一种普通 bean，另外一种工厂 bean（FactoryBean）</p>
</li>
<li><p>普通 bean：在配置文件中定义 bean 类型就是返回类型</p>
</li>
<li><p>工厂 bean：在配置文件定义 bean 类型可以和返回类型不一样</p>
<ol>
<li>创建类，让这个类作为工厂 bean，实现接口 FactoryBean</li>
<li>实现接口里面的方法，在实现的方法中定义返回的 bean 类型</li>
</ol>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MyBean</span> <span class="keyword">implements</span> <span class="title class_">FactoryBean</span>&lt;Course&gt; &#123;</span><br><span class="line">    <span class="comment">// 定义返回 bean 类型为 Course</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Course <span class="title function_">getObject</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="type">Course</span> <span class="variable">course</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Course</span>();</span><br><span class="line">        course.setCname(<span class="string">&quot;abc&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> course;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Class&lt;?&gt; getObjectType() &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isSingleton</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;myBean&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.factorybean.MyBean&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test</span><span class="params">()</span> &#123;</span><br><span class="line">	<span class="type">ApplicationContext</span> <span class="variable">context</span> <span class="operator">=</span> </span><br><span class="line">		<span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;bean.xml&quot;</span>);</span><br><span class="line">    <span class="type">Course</span> <span class="variable">course</span> <span class="operator">=</span> context.getBean(<span class="string">&quot;myBean&quot;</span>, Course.class);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>IOC 操作 Bean 管理（bean 作用域）</p>
<ul>
<li><p>在 Spring 里面，设置创建 bean 实例是单实例还是多实例（默认<strong>单实例对象</strong>）</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test</span><span class="params">()</span> &#123;</span><br><span class="line">	<span class="type">ApplicationContext</span> <span class="variable">context</span> <span class="operator">=</span> </span><br><span class="line">		<span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;bean.xml&quot;</span>);</span><br><span class="line">    <span class="type">Course</span> <span class="variable">course1</span> <span class="operator">=</span> context.getBean(<span class="string">&quot;myBean&quot;</span>, Course.class);</span><br><span class="line">    <span class="type">Course</span> <span class="variable">course2</span> <span class="operator">=</span> context.getBean(<span class="string">&quot;myBean&quot;</span>, Course.class);</span><br><span class="line">    <span class="comment">// 单实例对象，多次获取结果相同（为同一对象）</span></span><br><span class="line">    System.out.println(course1 == course2);	<span class="comment">// true</span></span><br><span class="line">    <span class="comment">// 若为多实例对象，则上述代码输出 false</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>设置 bean 为多实例对象</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--单实例(默认，可以不设置): 设置属性 scope=&quot;singleton&quot;--&gt;</span></span><br><span class="line"><span class="comment">&lt;!--多实例: 设置属性 scope=&quot;prototype&quot;--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;myBean&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.factorybean.MyBean&quot;</span> <span class="attr">scope</span>=<span class="string">&quot;prototype&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>singleton 和 prototype 区别</p>
<p>设置 scope 值是 singleton 时候，<strong>加载 spring 配置文件时候就会创建单实例对象</strong></p>
<p>设置 scope 值是 prototype 时候，不是在加载 spring 配置文件时候创建对象，而是<strong>在调用 getBean 方法时候创建多实例对象</strong></p>
</li>
</ul>
</li>
<li><p>IOC 操作 Bean 管理（bean 生命周期）</p>
<ul>
<li><p>生命周期：从对象创建到对象销毁的过程</p>
</li>
<li><p>bean 生命周期（5步）</p>
<ol>
<li><p>通过构造器创建 bean 实例（无参数构造方法）</p>
</li>
<li><p>设置 bean 的属性值和对其他 bean 引用（调用 set 方法）</p>
</li>
<li><p>调用 bean 的初始化的方法（需要在 xml 配置初始方法）</p>
</li>
<li><p>使用 bean（已获取 bean 对象）</p>
</li>
<li><p>当容器关闭时候，调用 bean 的销毁的方法（需要在 xml 配置销毁方法）</p>
</li>
</ol>
</li>
<li><p>演示 bean 生命周期（5步）</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Orders</span> &#123;</span><br><span class="line">    <span class="comment">// 无参构造器</span></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Orders</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;1.执行无参数构造创建 bean 实例&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">private</span> String oname;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setOname</span><span class="params">(String oname)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.oname = oname;</span><br><span class="line">        System.out.println(<span class="string">&quot;2.调用 set 方法设置属性值&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 创建执行的初始化的方法</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">initMethod</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;3.执行初始化的方法&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 创建执行的销毁的方法</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">destroyMethod</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;5.执行销毁的方法&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;orders&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.bean.Orders&quot;</span> <span class="attr">initmethod</span>=<span class="string">&quot;initMethod&quot;</span> <span class="attr">destroy-method</span>=<span class="string">&quot;destroyMethod&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;oname&quot;</span> <span class="attr">value</span>=<span class="string">&quot;手机&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testBean3</span><span class="params">()</span> &#123;</span><br><span class="line">     <span class="type">ClassPathXmlApplicationContext</span> <span class="variable">context</span> <span class="operator">=</span></span><br><span class="line">         <span class="keyword">new</span> <span class="title class_">ClassPathXmlApplicationContext</span>(<span class="string">&quot;bean4.xml&quot;</span>);</span><br><span class="line">     <span class="type">Orders</span> <span class="variable">orders</span> <span class="operator">=</span> context.getBean(<span class="string">&quot;orders&quot;</span>, Orders.class);</span><br><span class="line">     System.out.println(<span class="string">&quot;4.获取创建 bean 实例对象&quot;</span>);</span><br><span class="line">     System.out.println(orders);</span><br><span class="line">     <span class="comment">// 手动让 bean 实例销毁</span></span><br><span class="line">     context.close();</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>bean 生命周期（7步）——加上 bean 的后置处理器 <code>implements BeanPostProcessor</code></p>
<ol>
<li><p>通过构造器创建 bean 实例（无参数构造方法）</p>
</li>
<li><p>设置 bean 的属性值和对其他 bean 引用（调用 set 方法）</p>
</li>
<li><p><strong>把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization</strong> </p>
</li>
<li><p>调用 bean 的初始化的方法（需要在 xml 配置初始方法）</p>
</li>
<li><p><strong>把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization</strong></p>
</li>
<li><p>使用 bean（已获取 bean 对象）</p>
</li>
<li><p>当容器关闭时候，调用 bean 的销毁的方法（需要在 xml 配置销毁方法）</p>
</li>
</ol>
</li>
<li><p>演示 bean 生命周期（7步）</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MyBeanPost</span> <span class="keyword">implements</span> <span class="title class_">BeanPostProcessor</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Object <span class="title function_">postProcessBeforeInitialization</span><span class="params">(Object bean, String beanName)</span></span><br><span class="line">        <span class="keyword">throws</span> BeansException &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;3.在初始化之前执行的方法&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> bean;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Object <span class="title function_">postProcessAfterInitialization</span><span class="params">(Object bean, String beanName)</span></span><br><span class="line">        <span class="keyword">throws</span> BeansException &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;5.在初始化之后执行的方法&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> bean;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;myBeanPost&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.bean.MyBeanPost&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>IOC 操作 Bean 管理<strong>（xml 自动装配）</strong></p>
<ul>
<li><p>自动装配：根据指定装配规则（属性名称或者属性类型），Spring 自动将匹配的属性值进行注入</p>
<p>bean 标签属性 <code>autowire</code>，配置自动装配</p>
<ul>
<li><p>根据属性名称自动注入：<code>autowire=&quot;byName&quot;</code></p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--Emp 中有对象属性 Dept--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;emp&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.autowire.Emp&quot;</span> <span class="attr">autowire</span>=<span class="string">&quot;byName&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!--id 需与属性名 name 相同 dept--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;dept&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.autowire.Dept&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>根据属性类型自动注入：<code>autowire=&quot;byType&quot;</code></p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--Emp 中有对象属性 Dept--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;emp&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.autowire.Emp&quot;</span> <span class="attr">autowire</span>=<span class="string">&quot;byType&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!--相同 type 只能有一个属性，若有多个则 byName--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;dept&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.autowire.Dept&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
</li>
<li><p>IOC 操作 Bean 管理<strong>（外部属性文件）</strong></p>
<ul>
<li><p>手动配置数据库信息</p>
<ol>
<li><p>配置德鲁伊连接池</p>
</li>
<li><p>引入德鲁伊连接池依赖 jar 包</p>
</li>
</ol>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;dataSource&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.alibaba.druid.pool.DruidDataSource&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;driverClassName&quot;</span> <span class="attr">value</span>=<span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;url&quot;</span></span></span><br><span class="line"><span class="tag">              <span class="attr">value</span>=<span class="string">&quot;jdbc:mysql://localhost:3306/userDb&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;username&quot;</span> <span class="attr">value</span>=<span class="string">&quot;root&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;password&quot;</span> <span class="attr">value</span>=<span class="string">&quot;root&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>引入外部属性文件配置数据库连接池</p>
<ol>
<li><p>创建外部属性文件，properties 格式文件，写数据库信息</p>
<figure class="highlight properties"><table><tr><td class="code"><pre><span class="line"><span class="attr">prop.driverClass</span>=<span class="string">com.mysql.jdbc.Driver</span></span><br><span class="line"><span class="attr">prop.url</span>=<span class="string">jdbc:mysql://localhost:3306/userDb</span></span><br><span class="line"><span class="attr">prop.userName</span>=<span class="string">root</span></span><br><span class="line"><span class="attr">prop.password</span>=<span class="string">root</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>把外部 properties 属性文件引入到 spring 配置文件中</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://www.springframework.org/schema/beans&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:p</span>=<span class="string">&quot;http://www.springframework.org/schema/p&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:util</span>=<span class="string">&quot;http://www.springframework.org/schema/util&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:context</span>=<span class="string">&quot;http://www.springframework.org/schema/context&quot;</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://www.springframework.org/schema/beans</span></span></span><br><span class="line"><span class="string"><span class="tag">                           http://www.springframework.org/schema/beans/spring-beans.xsd</span></span></span><br><span class="line"><span class="string"><span class="tag">                           http://www.springframework.org/schema/util</span></span></span><br><span class="line"><span class="string"><span class="tag">                           http://www.springframework.org/schema/util/spring-util.xsd</span></span></span><br><span class="line"><span class="string"><span class="tag">                           http://www.springframework.org/schema/context</span></span></span><br><span class="line"><span class="string"><span class="tag">                           http://www.springframework.org/schema/context/spring-context.xsd&quot;</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>在 spring 配置文件使用标签引入外部属性文件</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--引入外部属性文件--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">context:property-placeholder</span> <span class="attr">location</span>=<span class="string">&quot;classpath:jdbc.properties&quot;</span>/&gt;</span></span><br><span class="line"><span class="comment">&lt;!--配置连接池--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;dataSource&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.alibaba.druid.pool.DruidDataSource&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;driverClassName&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;prop.driverClass&#125;&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;url&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;prop.url&#125;&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;username&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;prop.userName&#125;&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;password&quot;</span> <span class="attr">value</span>=<span class="string">&quot;$&#123;prop.password&#125;&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
</ol>
</li>
</ul>
</li>
<li><p><strong>基于注解方式实现 Bean 管理</strong></p>
<ul>
<li><p>注解的定义</p>
<ul>
<li>注解是代码特殊标记，格式：@注解名称(属性名称&#x3D;属性值, 属性名称&#x3D;属性值..) </li>
<li>使用注解，注解作用在<strong>类上面，方法上面，属性上面</strong></li>
<li>使用注解目的：简化 xml 配置</li>
</ul>
</li>
<li><p>Spring 针对 Bean 管理中创建对象提供注解</p>
<p>下面四个注解功能是一样的，都可以用来创建 bean 实例</p>
<ul>
<li>@Component：一般用作类的注解</li>
<li>@Service：一般用于业务层注解</li>
<li>@Controller：一般用于表现层注解</li>
<li>@Repository：一般用于持久层注解</li>
</ul>
</li>
</ul>
</li>
<li><p>基于注解方式实现对象创建</p>
<ol>
<li><p>引入 aop jar包</p>
</li>
<li><p>开启组件扫描</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--开启组件扫描，如果扫描多个包</span></span><br><span class="line"><span class="comment"> 1.多个包使用逗号隔开</span></span><br><span class="line"><span class="comment"> 2.或扫描包上层目录</span></span><br><span class="line"><span class="comment">--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">context:component-scan</span> <span class="attr">base-package</span>=<span class="string">&quot;com.atguigu&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">context:component-scan</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>创建类，并添加注解</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 在注解里面 value 属性值可以省略不写，</span></span><br><span class="line"><span class="comment">// 默认值是类名称，首字母小写</span></span><br><span class="line"><span class="comment">// UserService -- userService</span></span><br><span class="line"><span class="meta">@Component(value = &quot;userService&quot;)</span> </span><br><span class="line"><span class="comment">// 相当于&lt;bean id=&quot;userService&quot; class=&quot;..&quot;/&gt;</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;service add.......&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>开启组件扫描细节配置</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--示例 1</span></span><br><span class="line"><span class="comment"> use-default-filters=&quot;false&quot; 表示现在不使用默认 filter，自己配置 filter</span></span><br><span class="line"><span class="comment"> context:include-filter ，设置扫描哪些内容</span></span><br><span class="line"><span class="comment">--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">context:component-scan</span> <span class="attr">base-package</span>=<span class="string">&quot;com.atguigu&quot;</span> <span class="attr">use-defaultfilters</span>=<span class="string">&quot;false&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">context:include-filter</span> <span class="attr">type</span>=<span class="string">&quot;annotation&quot;</span> <span class="attr">expression</span>=<span class="string">&quot;org.springframework.stereotype.Controller&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">context:component-scan</span>&gt;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--示例 2</span></span><br><span class="line"><span class="comment"> 下面配置扫描包所有内容</span></span><br><span class="line"><span class="comment"> context:exclude-filter： 设置哪些内容不进行扫描</span></span><br><span class="line"><span class="comment">--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">context:component-scan</span> <span class="attr">base-package</span>=<span class="string">&quot;com.atguigu&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">context:exclude-filter</span> <span class="attr">type</span>=<span class="string">&quot;annotation&quot;</span> <span class="attr">expression</span>=<span class="string">&quot;org.springframework.stereotype.Controller&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">context:component-scan</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p><strong>基于注解方式实现属性注入</strong></p>
<ul>
<li><p>@Autowired：根据属性类型进行自动装配</p>
<ol>
<li>在 service 和 dao 类添加创建对象注解</li>
<li>在 service 注入 dao 对象，在 service 类添加 dao 类型属性，在属性上面使用注解</li>
</ol>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line">    <span class="comment">// 定义 dao 类型属性</span></span><br><span class="line">    <span class="comment">// 不需要添加 set 方法</span></span><br><span class="line">    <span class="comment">// 添加注入属性注解</span></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> UserDao userDao;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;service add.......&quot;</span>);</span><br><span class="line">        userDao.add();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>@Qualifier：根据名称进行注入</p>
<p>与 <code>@Autowired </code> 共同使用，解决同一类型的属性有多个的问题</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Autowired</span> 							<span class="comment">// 根据类型进行注入</span></span><br><span class="line"><span class="meta">@Qualifier(value = &quot;userDaoImpl1&quot;)</span> 	<span class="comment">// 根据名称进行注入</span></span><br><span class="line"><span class="keyword">private</span> UserDao userDao1;</span><br><span class="line"><span class="meta">@Qualifier(value = &quot;userDaoImpl2&quot;)</span> 	<span class="comment">// 根据名称进行注入</span></span><br><span class="line"><span class="keyword">private</span> UserDao userDao2;</span><br></pre></td></tr></table></figure>
</li>
<li><p>@Resource：可以根据类型注入，可以根据名称注入</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// @Resource 						// 根据类型进行注入</span></span><br><span class="line"><span class="meta">@Resource(name = &quot;userDaoImpl1&quot;)</span> 	<span class="comment">// 根据名称进行注入</span></span><br><span class="line"><span class="keyword">private</span> UserDao userDao;</span><br></pre></td></tr></table></figure>
</li>
<li><p>@Value：注入普通类型属性</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Value(value = &quot;abc&quot;)</span></span><br><span class="line"><span class="keyword">private</span> String name;</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ol>
</li>
<li><p><strong>完全注解开发</strong> </p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//（1）创建配置类，替代 xml 配置文件</span></span><br><span class="line"><span class="meta">@Configuration</span> <span class="comment">//作为配置类，替代 xml 配置文件</span></span><br><span class="line"><span class="meta">@ComponentScan(basePackages = &#123;&quot;com.atguigu&quot;&#125;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">SpringConfig</span> &#123;&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//（2）编写测试类</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testService2</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="comment">//加载配置类</span></span><br><span class="line">    <span class="type">ApplicationContext</span> <span class="variable">context</span></span><br><span class="line">        <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">AnnotationConfigApplicationContext</span>(SpringConfig.class);</span><br><span class="line">    <span class="type">UserService</span> <span class="variable">userService</span> <span class="operator">=</span> context.getBean(<span class="string">&quot;userService&quot;</span>,</span><br><span class="line">                                              UserService.class);</span><br><span class="line">    System.out.println(userService);</span><br><span class="line">    userService.add();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
</ul>
<h3 id="AOP（Aspect-Oriented-Programming）面向切面编程（方面）"><a href="#AOP（Aspect-Oriented-Programming）面向切面编程（方面）" class="headerlink" title="AOP（Aspect Oriented Programming）面向切面编程（方面）"></a>AOP（<strong>Aspect Oriented Programming</strong>）面向切面编程（方面）</h3><ul>
<li><p>定义：面向切面编程（方面），利用 AOP 可以对业务逻辑的各个部分进行隔离，从而使得 业务逻辑各部分之间的耦合度降低，提高程序的可重用性，同时提高了开发的效率</p>
</li>
<li><p>通俗描述：<strong>不通过修改源代码方式，在主干功能里面添加新功能</strong></p>
<p>如给登录功能添加权限检查模块</p>
</li>
<li><p>AOP 底层原理——动态代理</p>
<ul>
<li><p>有接口情况，使用 JDK 动态代理</p>
<p><img src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/Spring/qdgPOJ.png" alt="qdgPOJ.png"></p>
<p>使用 Proxy 类里面的方法创建代理对象</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 1.创建接口，定义方法</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">UserDao</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">add</span><span class="params">(<span class="type">int</span> a,<span class="type">int</span> b)</span>;</span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">update</span><span class="params">(String id)</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2.创建接口实现类，实现方法</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">UserDao</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">add</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> a + b;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">update</span><span class="params">(String id)</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> id;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 3.创建代理对象代码</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">UserDaoProxy</span> <span class="keyword">implements</span> <span class="title class_">InvocationHandler</span> &#123;</span><br><span class="line">    <span class="comment">// 1.创建的是 A 的代理对象，把 A 传递过来</span></span><br><span class="line">    <span class="comment">// 2.有参数构造传递</span></span><br><span class="line">    <span class="keyword">private</span> Object obj;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">UserDaoProxy</span><span class="params">(Object obj)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.obj = obj;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 增强的逻辑</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Object <span class="title function_">invoke</span><span class="params">(Object proxy, Method method, Object[] args)</span> <span class="keyword">throws</span></span><br><span class="line">        Throwable &#123;</span><br><span class="line">        	<span class="comment">// 方法之前</span></span><br><span class="line">        	System.out.println(<span class="string">&quot;方法之前执行....&quot;</span> + method.getName() + <span class="string">&quot; :传递的参数...&quot;</span>+ Arrays.toString(args));</span><br><span class="line">           <span class="comment">// 被增强的方法执行</span></span><br><span class="line">           <span class="type">Object</span> <span class="variable">res</span> <span class="operator">=</span> method.invoke(obj, args);</span><br><span class="line">           <span class="comment">// 方法之后</span></span><br><span class="line">           System.out.println(<span class="string">&quot;方法之后执行....&quot;</span> + obj); </span><br><span class="line">           <span class="keyword">return</span> res;</span><br><span class="line">       &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 4.使用 Proxy 类创建接口代理对象</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">JDKProxy</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="comment">// 创建接口实现类代理对象</span></span><br><span class="line">        <span class="type">UserDaoImpl</span> <span class="variable">userDao</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">UserDaoImpl</span>();</span><br><span class="line">        <span class="type">UserDao</span> <span class="variable">dao</span> <span class="operator">=</span> (UserDao)Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces,<span class="keyword">new</span> <span class="title class_">UserDaoProxy</span>(userDao));</span><br><span class="line">        <span class="type">int</span> <span class="variable">result</span> <span class="operator">=</span> dao.add(<span class="number">1</span>, <span class="number">2</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;result:&quot;</span>+result);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>没有接口情况，使用 CGLIB 动态代理</p>
<p><img src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/Spring/qdgCy4.png" alt="qdgCy4.png"></p>
</li>
</ul>
</li>
<li><p>AOP 常用术语</p>
<ul>
<li>连接点：类里面可以被增强的方法</li>
<li>切入点：实际被真正增强的方法</li>
<li>通知（增强） <ul>
<li>实际增强的逻辑部分称为通知（增强）</li>
<li>通知有多种类型<ul>
<li>前置通知</li>
<li>后置通知</li>
<li>环绕通知</li>
<li>异常通知</li>
<li>最终通知</li>
</ul>
</li>
</ul>
</li>
<li>切面：是动作，即把通知应用到切入点的过程</li>
</ul>
</li>
<li><p>AOP操作准备工作</p>
<ol>
<li><p>Spring 框架一般都是基于 AspectJ 实现 AOP 操作</p>
<p>AspectJ 不是 Spring 组成部分，独立 AOP 框架，一般把 AspectJ 和 Spirng 框架一起使 用，进行 AOP 操</p>
</li>
<li><p>基于 <code>AspectJ</code> 实现 AOP 操作</p>
<ul>
<li>基于 xml 配置文件实现</li>
<li>基于注解方式实现（推荐）</li>
</ul>
</li>
<li><p>在项目工程里面引入 AOP 相关依赖</p>
<p><img src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/Spring/qd45He.png" alt="qd45He.png"></p>
</li>
<li><p>切入点表达式</p>
<ul>
<li><p>切入点表达式作用：知道对哪个类里面的哪个方法进行增强 </p>
</li>
<li><p>语法结构： <code>execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]) )</code></p>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 举例1: 对 com.atguigu.dao.BookDao 类里面的 add 进行增强</span></span><br><span class="line">execution(* com.atguigu.dao.BookDao.add(..))</span><br><span class="line">    </span><br><span class="line"><span class="comment">// 举例2: 对 com.atguigu.dao.BookDao 类里面的所有的方法进行增强</span></span><br><span class="line">execution(* com.atguigu.dao.BookDao.* (..))</span><br><span class="line">    </span><br><span class="line"><span class="comment">// 举例3: 对 com.atguigu.dao 包里面所有类，类里面所有方法进行增强</span></span><br><span class="line">execution(* com.atguigu.dao.*.* (..))</span><br></pre></td></tr></table></figure></li>
</ol>
</li>
<li><p><strong>AOP 操作（AspectJ 注解实现，推荐）</strong></p>
<ol>
<li>创建类，在类里面定义方法</li>
<li>创建增强类（编写增强逻辑）</li>
<li>进行通知的配置</li>
<li>配置不同类型的通知</li>
<li>相同的切入点抽取</li>
<li>有多个增强类多同一个方法进行增强，设置增强类优先级</li>
<li>完全使用注解开发</li>
</ol>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 1.创建类，在类里面定义方法</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">User</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;add.......&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 2.创建增强类（编写增强逻辑）</span></span><br><span class="line"><span class="comment">// 在增强类里面，创建方法，让不同方法代表不同通知类型</span></span><br><span class="line"><span class="comment">// 增强的类</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="meta">@Aspect</span>		<span class="comment">// 生成代理对象</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserProxy</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">before</span><span class="params">()</span> &#123;	<span class="comment">// 前置通知</span></span><br><span class="line">        System.out.println(<span class="string">&quot;before......&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 3.进行通知的配置</span></span><br><span class="line"><span class="comment">	(1)在 spring 配置文件中，开启注解扫描</span></span><br><span class="line"><span class="comment">	(2)使用注解创建 User 和 UserProxy 对象</span></span><br><span class="line"><span class="comment">	(3)在增强类上面添加注解 @Aspect</span></span><br><span class="line"><span class="comment">	(4)在 spring 配置文件中开启生成代理对象</span></span><br><span class="line"><span class="comment">--&gt;</span></span><br><span class="line"><span class="comment">&lt;!--(1)开启注解扫描--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">context:component-scan</span> <span class="attr">basepackage</span>=<span class="string">&quot;com.atguigu.spring5.aopanno&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">context:component-scan</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!--(2)使用注解创建 User 和 UserProxy 对象--&gt;</span></span><br><span class="line"><span class="comment">&lt;!--(3)在增强类上面添加注解 @Aspect 对象--&gt;</span></span><br><span class="line"><span class="comment">&lt;!--(4)在 spring 配置文件中开启生成代理对象--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">aop:aspectj-autoproxy</span>&gt;</span><span class="tag">&lt;/<span class="name">aop:aspectj-autoproxy</span>&gt;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 4.配置不同类型的通知</span></span><br><span class="line"><span class="comment">// 在增强类的里面，在作为通知方法上面添加通知类型注解，使用切入点表达式配置</span></span><br><span class="line"><span class="comment">// 增强的类</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="meta">@Aspect</span> <span class="comment">// 生成代理对象</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserProxy</span> &#123;</span><br><span class="line">    <span class="comment">// 前置通知</span></span><br><span class="line">    <span class="meta">@Before(value = &quot;execution(* com.atguigu.spring5.aopanno.User.add(..))&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">before</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;before.........&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 后置通知（返回通知）</span></span><br><span class="line">    <span class="meta">@AfterReturning(value = &quot;execution(* com.atguigu.spring5.aopanno.User.add(..))&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">afterReturning</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;afterReturning.........&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 最终通知</span></span><br><span class="line">    <span class="meta">@After(value = &quot;execution(* com.atguigu.spring5.aopanno.User.add(..))&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">after</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;after.........&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 异常通知</span></span><br><span class="line">    <span class="meta">@AfterThrowing(value = &quot;execution(* com.atguigu.spring5.aopanno.User.add(..))&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">afterThrowing</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;afterThrowing.........&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 环绕通知</span></span><br><span class="line">    <span class="meta">@Around(value = &quot;execution(* com.atguigu.spring5.aopanno.User.add(..))&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">around</span><span class="params">(ProceedingJoinPoint proceedingJoinPoint)</span> <span class="keyword">throws</span></span><br><span class="line">        Throwable &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;环绕之前.........&quot;</span>);</span><br><span class="line">        <span class="comment">// 被增强的方法执行</span></span><br><span class="line">        proceedingJoinPoint.proceed();</span><br><span class="line">        System.out.println(<span class="string">&quot;环绕之后.........&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 5.相同的切入点抽取</span></span><br><span class="line"><span class="comment">// 相同切入点抽取</span></span><br><span class="line"><span class="meta">@Pointcut(value = &quot;execution(* com.atguigu.spring5.aopanno.User.add(..))&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">pointdemo</span><span class="params">()</span> &#123;&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 前置通知</span></span><br><span class="line"><span class="meta">@Before(value = &quot;pointdemo()&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">before</span><span class="params">()</span> &#123;</span><br><span class="line">	System.out.println(<span class="string">&quot;before.........&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 6.有多个增强类多同一个方法进行增强，设置增强类优先级</span></span><br><span class="line"><span class="comment">// 在增强类上面添加注解 @Order(数字类型值)，数字类型值越小优先级越高</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="meta">@Aspect</span></span><br><span class="line"><span class="meta">@Order(1)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">PersonProxy</span></span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 7.完全使用注解开发 </span></span><br><span class="line"><span class="comment">// 创建配置类，不需要创建 xml 配置文件</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@ComponentScan(basePackages = &#123;&quot;com.atguigu&quot;&#125;)</span></span><br><span class="line"><span class="meta">@EnableAspectJAutoProxy(proxyTargetClass = true)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ConfigAop</span> &#123;&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>AOP 操作（AspectJ 配置文件实现）</p>
<ol>
<li><p>创建两个类，增强类和被增强类，创建方法</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 被增强类</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Book</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">buy</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;buy...&quot;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 增强类</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookProxy</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">before</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;before...&quot;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>在 spring 配置文件中创建两个类对象</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--创建对象--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;book&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.aopxml.Book&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;bookProxy&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.atguigu.spring5.aopxml.BookProxy&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>在 spring 配置文件中配置切入点</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--配置 aop 增强--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">aop:config</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--切入点--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">aop:pointcut</span> <span class="attr">id</span>=<span class="string">&quot;p&quot;</span> <span class="attr">expression</span>=<span class="string">&quot;execution(* com.atguigu.spring5.aopxml.Book.buy(..))&quot;</span>/&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--配置切面--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">aop:aspect</span> <span class="attr">ref</span>=<span class="string">&quot;bookProxy&quot;</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--增强作用在具体的方法上--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">aop:before</span> <span class="attr">method</span>=<span class="string">&quot;before&quot;</span> <span class="attr">pointcut-ref</span>=<span class="string">&quot;p&quot;</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">aop:aspect</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">aop:config</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
</ol>
</li>
</ul>
<h3 id="JdbcTemplate（对-JDBC-的封装，用于操作数据库）"><a href="#JdbcTemplate（对-JDBC-的封装，用于操作数据库）" class="headerlink" title="JdbcTemplate（对 JDBC 的封装，用于操作数据库）"></a>JdbcTemplate（对 JDBC 的封装，用于操作数据库）</h3><ul>
<li><p>JdbcTemplate 基本概念</p>
<ul>
<li><p>JdbcTemplate  定义</p>
<p>Spring 框架对 JDBC 进行封装，使用 JdbcTemplate 方便实现对数据库操作</p>
</li>
<li><p>准备工作</p>
<ol>
<li><p>引入相关 jar 包</p>
<p><a target="_blank" rel="noopener" href="https://imgtu.com/i/qwydrd"><img src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/Spring/qwydrd.png" alt="qwydrd.png" style="zoom:80%;" /></a></p>
</li>
<li><p>在 spring 配置文件配置数据库连接池</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 数据库连接池 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;dataSource&quot;</span> <span class="attr">class</span>=<span class="string">&quot;com.alibaba.druid.pool.DruidDataSource&quot;</span></span></span><br><span class="line"><span class="tag">      <span class="attr">destroy-method</span>=<span class="string">&quot;close&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;url&quot;</span> <span class="attr">value</span>=<span class="string">&quot;jdbc:mysql:///user_db&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;username&quot;</span> <span class="attr">value</span>=<span class="string">&quot;root&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;password&quot;</span> <span class="attr">value</span>=<span class="string">&quot;root&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;driverClassName&quot;</span> <span class="attr">value</span>=<span class="string">&quot;com.mysql.jdbc.Driver&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>配置 JdbcTemplate 对象，注入 DataSource</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!-- JdbcTemplate 对象 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;jdbcTemplate&quot;</span> <span class="attr">class</span>=<span class="string">&quot;org.springframework.jdbc.core.JdbcTemplate&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--注入 dataSource--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;dataSource&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;dataSource&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>创建 service 类，创建 dao 类，在 dao 注入 jdbcTemplate 对象</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line">* 配置文件</span><br><span class="line"><span class="comment">&lt;!-- 组件扫描 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">context:component-scan</span> <span class="attr">base-package</span>=<span class="string">&quot;com.atguigu&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">context:component-scan</span>&gt;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookService</span> &#123;</span><br><span class="line">    <span class="comment">//注入 dao</span></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> BookDao bookDao;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Repository</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="comment">//注入 JdbcTemplate</span></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> JdbcTemplate jdbcTemplate;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
</ol>
</li>
</ul>
</li>
<li><p>JdbcTemplate 操作数据库</p>
<ol>
<li><p>创建对应数据库的实体类（Bean）</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">User</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> String userId;</span><br><span class="line">    <span class="keyword">private</span> String username;</span><br><span class="line">    <span class="keyword">private</span> String ustatus;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setUserId</span><span class="params">(String userId)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.userId = userId;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">serUsername</span><span class="params">(String username)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.username = username;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">serUsername</span><span class="params">(String ustatus)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.ustatus = ustatus;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>编写 service 和 dao（同上）</p>
</li>
<li><p>添加操作</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Repository</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BookDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">BookDao</span> &#123;</span><br><span class="line">    <span class="comment">// 注入 JdbcTemplate</span></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> JdbcTemplate jdbcTemplate;</span><br><span class="line">    <span class="comment">// 添加的方法</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">(Book book)</span> &#123;</span><br><span class="line">        <span class="comment">// 1.创建 sql 语句</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;insert into t_book values(?,?,?)&quot;</span>;</span><br><span class="line">        <span class="comment">// 2.调用方法实现</span></span><br><span class="line">        Object[] args = &#123;book.getUserId(), book.getUsername(),</span><br><span class="line">                         book.getUstatus()&#125;;</span><br><span class="line">        <span class="type">int</span> <span class="variable">update</span> <span class="operator">=</span> jdbcTemplate.update(sql, args);</span><br><span class="line">        System.out.println(update);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>修改操作</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">updateBook</span><span class="params">(Book book)</span> &#123;</span><br><span class="line">    <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;update t_book set username=?,ustatus=? where user_id=?&quot;</span>;</span><br><span class="line">    Object[] args = &#123;book.getUsername(), book.getUstatus(),book.getUserId()&#125;;</span><br><span class="line">    <span class="type">int</span> <span class="variable">update</span> <span class="operator">=</span> jdbcTemplate.update(sql, args);</span><br><span class="line">    System.out.println(update);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>删除操作</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">delete</span><span class="params">(String id)</span> &#123;</span><br><span class="line">    <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;delete from t_book where user_id=?&quot;</span>;</span><br><span class="line">    <span class="type">int</span> <span class="variable">update</span> <span class="operator">=</span> jdbcTemplate.update(sql, id);</span><br><span class="line">    System.out.println(update);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>查询操作</p>
<ul>
<li>查询返回某个值</li>
<li>查询返回对象</li>
<li>查询返回集合</li>
</ul>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 查询返回某个值</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="type">int</span> <span class="title function_">selectCount</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;select count(*) from t_book&quot;</span>;</span><br><span class="line">    <span class="type">Integer</span> <span class="variable">count</span> <span class="operator">=</span> jdbcTemplate.queryForObject(sql, Integer.class);</span><br><span class="line">    <span class="keyword">return</span> count;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 查询返回对象</span></span><br><span class="line"><span class="comment">// RowMapper 是接口，针对返回不同类型数据，使用这个接口里面实现类 BeanPropertyRowMapper 完成数据封装</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> Book <span class="title function_">findBookInfo</span><span class="params">(String id)</span> &#123;</span><br><span class="line">    <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;select * from t_book where user_id=?&quot;</span>;</span><br><span class="line">    <span class="comment">//调用方法</span></span><br><span class="line">    <span class="type">Book</span> <span class="variable">book</span> <span class="operator">=</span> jdbcTemplate.queryForObject(sql, <span class="keyword">new</span> <span class="title class_">BeanPropertyRowMapper</span>&lt;Book&gt;(Book.class), id);</span><br><span class="line">    <span class="keyword">return</span> book;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 查询返回集合</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> List&lt;Book&gt; <span class="title function_">findAllBook</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;select * from t_book&quot;</span>;</span><br><span class="line">    <span class="comment">//调用方法</span></span><br><span class="line">    List&lt;Book&gt; bookList = jdbcTemplate.query(sql, <span class="keyword">new</span> <span class="title class_">BeanPropertyRowMapper</span>&lt;Book&gt;(Book.class));</span><br><span class="line">    <span class="keyword">return</span> bookList;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>批量操作：操作表里面多条记录</p>
<ul>
<li><p>批量添加</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">batchAddBook</span><span class="params">(List&lt;Object[]&gt; batchArgs)</span> &#123;</span><br><span class="line">    <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;insert into t_book values(?,?,?)&quot;</span>;</span><br><span class="line">    <span class="type">int</span>[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);</span><br><span class="line">    System.out.println(Arrays.toString(ints));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>批量修改</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">batchUpdateBook</span><span class="params">(List&lt;Object[]&gt; batchArgs)</span> &#123;</span><br><span class="line">    <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;update t_book set username=?,ustatus=? where user_id=?&quot;</span>;</span><br><span class="line">    <span class="type">int</span>[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);</span><br><span class="line">    System.out.println(Arrays.toString(ints));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>批量删除</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">batchDeleteBook</span><span class="params">(List&lt;Object[]&gt; batchArgs)</span> &#123;</span><br><span class="line">    <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;delete from t_book where user_id=?&quot;</span>;</span><br><span class="line">    <span class="type">int</span>[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);</span><br><span class="line">    System.out.println(Arrays.toString(ints));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ol>
</li>
</ul>
<h3 id="事务"><a href="#事务" class="headerlink" title="事务"></a>事务</h3><ul>
<li><p>定义：事务是数据库操作最基本单元，逻辑上一组操作，要么都成功，如果有一个失败所有操作都失败</p>
</li>
<li><p>事务四个特性（ACID）：原子性、一致性、隔离性、持久性</p>
</li>
<li><p>搭建事务操作环境</p>
<p><a target="_blank" rel="noopener" href="https://imgtu.com/i/qwhE1x"><img src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/Spring/qwhE1x.png" alt="qwhE1x.png"></a></p>
<ol>
<li><p>创建 service，搭建 dao，完成对象创建和注入关系</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line">    <span class="comment">//注入 dao</span></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> UserDao userDao;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Repository</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">UserDao</span> &#123;</span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> JdbcTemplate jdbcTemplate;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>在 dao 创建两个方法：多钱和少钱的方法，在 service 创建方法（转账的方法）</p>
<p>如下代码如果正常执行没有问题的，但是如果代码执行过程中出现异常，则会出现问题</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Repository</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserDaoImpl</span> <span class="keyword">implements</span> <span class="title class_">UserDao</span> &#123;</span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> JdbcTemplate jdbcTemplate;</span><br><span class="line">    <span class="comment">// lucy 转账 100 给 mary</span></span><br><span class="line">    <span class="comment">// 少钱</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">reduceMoney</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;update t_account set money=money-? where username=?&quot;</span>;</span><br><span class="line">        jdbcTemplate.update(sql,<span class="number">100</span>,<span class="string">&quot;lucy&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 多钱</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">addMoney</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">sql</span> <span class="operator">=</span> <span class="string">&quot;update t_account set money=money+? where username=?&quot;</span>;</span><br><span class="line">        jdbcTemplate.update(sql,<span class="number">100</span>,<span class="string">&quot;mary&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserService</span> &#123;</span><br><span class="line">    <span class="comment">// 注入 dao</span></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> UserDao userDao;</span><br><span class="line">    <span class="comment">// 转账的方法</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accountMoney</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="comment">// lucy 少 100</span></span><br><span class="line">        userDao.reduceMoney();</span><br><span class="line">        <span class="comment">// mary 多 100</span></span><br><span class="line">        userDao.addMoney();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
</ol>
</li>
<li><p>事务操作（Spring 事务管理介绍）</p>
<ul>
<li><p>事务添加到 JavaEE 三层结构里面 Service 层（业务逻辑层）</p>
</li>
<li><p>在 Spring 进行事务管理操作有两种方式：</p>
<ul>
<li>编程式事务管理</li>
<li><strong>声明式事务管理（推荐使用）</strong></li>
</ul>
</li>
<li><p>声明式事务管理</p>
<ul>
<li><strong>基于注解方式（推荐使用）</strong></li>
<li>基于 xml 配置文件方式</li>
</ul>
</li>
<li><p>在 Spring 进行声明式事务管理，底层使用 AOP 原理</p>
</li>
<li><p>Spring 事务管理 API：<code>PlatformTransactionManager</code></p>
<p>这个 API 针对不同的框架提供不同的实现类，如 <code>DataSourceTransactionManager</code></p>
</li>
</ul>
</li>
<li><p><strong>事务操作（注解声明式事务管理）</strong></p>
<ol>
<li><p>在 spring 配置文件配置事务管理器</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--创建事务管理器--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;transactionManager&quot;</span> <span class="attr">class</span>=<span class="string">&quot;org.springframework.jdbc.datasource.DataSourceTransactionManager&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--注入数据源--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;dataSource&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;dataSource&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>在 spring 配置文件，开启事务注解</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--开启事务注解--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">tx:annotation-driven</span> <span class="attr">transactionmanager</span>=<span class="string">&quot;transactionManager&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">tx:annotation-driven</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>在 service 类上面（或者 service 类里面方法上面）添加事务注解</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 1.@Transactional，这个注解添加到类上面，也可以添加方法上面</span></span><br><span class="line"><span class="comment">// 2.如果把这个注解添加类上面，这个类里面所有的方法都添加事务</span></span><br><span class="line"><span class="comment">// 3.如果把这个注解添加方法上面，为这个方法添加事务</span></span><br><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="meta">@Transactional</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserService</span> &#123;&#125;</span><br></pre></td></tr></table></figure></li>
</ol>
</li>
<li><p>事务操作（声明式事务管理参数配置）</p>
<p>在 service 类上面添加注解@Transactional，在这个注解里面可以配置事务相关参数</p>
<p> <img src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/Spring/q0K6SS.png" alt="q0K6SS.png"></p>
<ol>
<li><p>propagation：事务传播行为：多事务方法直接进行调用，这个过程中事务是如何进行管理的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Transactional(propagation=Propagation.REQURIED)</span></span><br></pre></td></tr></table></figure>

 <img src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/Spring/q0METI.png" alt="q0METI.png" style="zoom:67%;" />
</li>
<li><p>ioslation：事务隔离级别:事务有隔离性，多事务操作之间不会产生影响</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Transactional(propagation=Propagation.REQURIED, isolation=Iolation.REPEATABLE_READ)</span></span><br></pre></td></tr></table></figure>

<ul>
<li>脏读：一个未提交事务读取到另一个未提交事务的数据</li>
<li>不可重复读：一个未提交事务读取到另一提交事务修改数据</li>
<li>虚读（幻读）：一个未提交事务读取到另一提交事务添加 &#x2F; 删除数据</li>
</ul>
<p><a target="_blank" rel="noopener" href="https://imgtu.com/i/q0Ql8K"><img src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/Spring/q0Ql8K.png" alt="q0Ql8K.png"></a></p>
</li>
<li><p>timeout：超时时间</p>
<ul>
<li><p>事务需要在一定时间内进行提交，如果不提交进行回滚</p>
</li>
<li><p>默认值是 -1 ，设置时间以秒单位进行计算</p>
</li>
</ul>
</li>
<li><p>readOnly：是否只读</p>
<ul>
<li>读：查询操作，写：添加修改删除操作</li>
<li>readOnly 默认值 false，表示可以进行查询、添加、修改、删除操作</li>
<li>设置 readOnly 值是 true，表示只能查询</li>
</ul>
</li>
<li><p>rollbackFor：回滚</p>
<ul>
<li>设置出现哪些异常进行事务回滚</li>
</ul>
</li>
<li><p>noRollbackFor：不回滚</p>
<ul>
<li>设置出现哪些异常不进行事务回滚</li>
</ul>
</li>
</ol>
</li>
<li><p>事务操作（XML 声明式事务管理）</p>
<ol>
<li>配置事务管理器</li>
<li>配置通知</li>
<li>配置切入点和切面</li>
</ol>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment">&lt;!--1 创建事务管理器--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">&quot;transactionManager&quot;</span></span></span><br><span class="line"><span class="tag">      <span class="attr">class</span>=<span class="string">&quot;org.springframework.jdbc.datasource.DataSourceTransactionManager&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--注入数据源--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">&quot;dataSource&quot;</span> <span class="attr">ref</span>=<span class="string">&quot;dataSource&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!--2 配置通知--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">tx:advice</span> <span class="attr">id</span>=<span class="string">&quot;txadvice&quot;</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--配置事务参数--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">tx:attributes</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--指定哪种规则的方法上面添加事务--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">tx:method</span> <span class="attr">name</span>=<span class="string">&quot;accountMoney&quot;</span> <span class="attr">propagation</span>=<span class="string">&quot;REQUIRED&quot;</span>/&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--&lt;tx:method name=&quot;account*&quot;/&gt;--&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">tx:attributes</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">tx:advice</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!--3 配置切入点和切面--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">aop:config</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--配置切入点--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">aop:pointcut</span> <span class="attr">id</span>=<span class="string">&quot;pt&quot;</span> <span class="attr">expression</span>=<span class="string">&quot;execution(* com.atguigu.spring5.service.UserService.*(..))&quot;</span>/&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--配置切面--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">aop:advisor</span> <span class="attr">advice-ref</span>=<span class="string">&quot;txadvice&quot;</span> <span class="attr">pointcut-ref</span>=<span class="string">&quot;pt&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">aop:config</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>事务操作（完全注解声明式事务管理）</p>
<p>创建配置类，使用配置类替代 xml 配置文件</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Configuration</span> 									<span class="comment">// 配置类</span></span><br><span class="line"><span class="meta">@ComponentScan(basePackages = &quot;com.atguigu&quot;)</span> 	<span class="comment">// 组件扫描</span></span><br><span class="line"><span class="meta">@EnableTransactionManagement</span> 					<span class="comment">// 开启事务</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">TxConfig</span> &#123;</span><br><span class="line">    <span class="comment">// 创建数据库连接池</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> DruidDataSource <span class="title function_">getDruidDataSource</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">DruidDataSource</span> <span class="variable">dataSource</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">DruidDataSource</span>();</span><br><span class="line">        dataSource.setDriverClassName(<span class="string">&quot;com.mysql.jdbc.Driver&quot;</span>);</span><br><span class="line">        dataSource.setUrl(<span class="string">&quot;jdbc:mysql:///user_db&quot;</span>);</span><br><span class="line">        dataSource.setUsername(<span class="string">&quot;root&quot;</span>);</span><br><span class="line">        dataSource.setPassword(<span class="string">&quot;root&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> dataSource;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 创建 JdbcTemplate 对象</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> JdbcTemplate <span class="title function_">getJdbcTemplate</span><span class="params">(DataSource dataSource)</span> &#123;</span><br><span class="line">        <span class="comment">//到 ioc 容器中根据类型找到 dataSource</span></span><br><span class="line">        <span class="type">JdbcTemplate</span> <span class="variable">jdbcTemplate</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JdbcTemplate</span>();</span><br><span class="line">        <span class="comment">//注入 dataSource</span></span><br><span class="line">        jdbcTemplate.setDataSource(dataSource);</span><br><span class="line">        <span class="keyword">return</span> jdbcTemplate;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 创建事务管理器</span></span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> DataSourceTransactionManager</span><br><span class="line">        <span class="title function_">getDataSourceTransactionManager</span><span class="params">(DataSource dataSource)</span> &#123;</span><br><span class="line">        <span class="type">DataSourceTransactionManager</span> <span class="variable">transactionManager</span> <span class="operator">=</span> <span class="keyword">new</span></span><br><span class="line">            <span class="title class_">DataSourceTransactionManager</span>();</span><br><span class="line">        transactionManager.setDataSource(dataSource);</span><br><span class="line">        <span class="keyword">return</span> transactionManager;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
</ul>
<h3 id="Spring5-框架新功能"><a href="#Spring5-框架新功能" class="headerlink" title="Spring5 框架新功能"></a>Spring5 框架新功能</h3><ul>
<li><p>整个 Spring5 框架的代码基于 Java8，运行时兼容 JDK9，许多不建议使用的类和方法在代码库中删除</p>
</li>
<li><p>Spring 5.0 框架自带了通用的日志封装</p>
<p>Spring5 已经移除 Log4jConfigListener，官方建议使用 Log4j2</p>
</li>
<li><p>Spring5 框架核心容器支持@Nullable 注解</p>
<p><strong>@Nullable 注解可以使用在方法上面 (方法返回可以为空)，属性上面 (属性值可以为空)，参数上面 (参数值可以为空)</strong></p>
</li>
<li><p>Spring5 核心容器支持函数式风格 GenericApplicationContext（Lambda表达式）</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 函数式风格创建对象，交给 spring 进行管理</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testGenericApplicationContext</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="comment">// 1.创建 GenericApplicationContext 对象</span></span><br><span class="line">    <span class="type">GenericApplicationContext</span> <span class="variable">context</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">GenericApplicationContext</span>();</span><br><span class="line">    <span class="comment">// 2.调用 context 的方法对象注册</span></span><br><span class="line">    context.refresh();</span><br><span class="line">    context.registerBean(<span class="string">&quot;user1&quot;</span>, User.class, () -&gt; <span class="keyword">new</span> <span class="title class_">User</span>());</span><br><span class="line">    <span class="comment">// 3.获取在 spring 注册的对象</span></span><br><span class="line">    <span class="comment">// User user = (User)context.getBean(&quot;com.atguigu.spring5.test.User&quot;);</span></span><br><span class="line">    <span class="type">User</span> <span class="variable">user</span> <span class="operator">=</span> (User)context.getBean(<span class="string">&quot;user1&quot;</span>);</span><br><span class="line">    System.out.println(user);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>Spring5 支持整合 JUnit5（用于测试 <code>@Test</code>）</p>
</li>
</ul>
<h3 id="Spring5-框架新功能（Webflux）"><a href="#Spring5-框架新功能（Webflux）" class="headerlink" title="Spring5 框架新功能（Webflux）"></a>Spring5 框架新功能（Webflux）</h3><ul>
<li><p>SpringWebflux：是 Spring5 添加新的模块，用于 web 开发的，功能和 SpringMVC 类似的，Webflux 使用当前一种比较流程<strong>响应式编程</strong>出现的框架</p>
</li>
<li><p>使用传统 web 框架，比如 SpringMVC，这些基于 Servlet 容器，Webflux 是一种异步非阻塞的框架，异步非阻塞的框架在 Servlet3.1 以后才支持，核心是基于 Reactor 的相关 API 实现的</p>
</li>
<li><p><strong>异步非阻塞</strong></p>
<ul>
<li><strong>异步和同步</strong>：针对调用者，调用者发送请求，如果等着对方回应之后才去做其他事情就是同步，如果发送请求之后不等着对方回应就去做其他事情就是异步</li>
<li><strong>阻塞和非阻塞</strong>：针对被调用者，被调用者受到请求之后，做完请求任务之后才给出反馈就是阻塞，受到请求之后马上给出反馈然后再去做事情就是非阻塞</li>
</ul>
</li>
<li><p>Webflux 特点</p>
<ul>
<li>非阻塞式：在有限资源下，提高系统吞吐量和伸缩性，以 Reactor 为基础实现响应式编程</li>
<li>函数式编程：Spring5 框架基于 java8，Webflux 使用 Java8 函数式编程方式实现路由请求</li>
</ul>
</li>
<li><p>与 SpringMVC 比较</p>
<ul>
<li>两个框架都可以使用注解方式，都运行在 Tomet 等容器中</li>
<li>SpringMVC 采用<strong>命令式编程</strong>，Webflux 采用<strong>异步响应式编程</strong></li>
</ul>
 <img src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/Spring/q0zIa9.png" alt="q0zIa9.png" style="zoom:80%;" />
</li>
<li><p>响应式编程</p>
<p>响应式编程是一种面向<strong>数据流</strong>和<strong>变化传播</strong>的编程范式。这意味着可以在编程语言中很方便地表达静态或动态的数据流，而相关的计算模型会自动将变化的值通过数据流进行传播。 电子表格程序就是响应式编程的一个例子。单元格可以包含字面值或类似”&#x3D;B1+C1”的公式，而包含公式的单元格的值会依据其他单元格的值的变化而变化。</p>
</li>
<li><p>Java8 及其之前版本</p>
<p>提供的<strong>观察者模式</strong>两个类 <code>Observer</code> 和 <code>Observable</code></p>
</li>
<li><p>响应式编程（Reactor 实现）</p>
<ul>
<li>响应式编程操作中，Reactor 是满足 Reactive 规范框架</li>
<li>Reactor 有两个核心类，Mono 和 Flux，这两个类实现接口 Publisher，提供丰富操作符。Flux 对象实现发布者，返回 N 个元素；Mono 实现发布者，返回 0 或者 1 个元素</li>
<li>Flux 和 Mono 都是数据流的发布者，使用 Flux 和 Mono 都可以发出三种数据信号： <strong>元素值，错误信号，完成信号</strong></li>
<li>错误信号和完成信号都代表终止信号，终止信号用于告诉订阅者数据流结束了，错误信号终止数据流同时把错误信息传递给订阅者</li>
<li>三种信号特点<ul>
<li>错误信号和完成信号都是终止信号，不能共存的</li>
<li>如果没有发送任何元素值，而是直接发送错误或者完成信号，表示是<strong>空数据流</strong></li>
<li>如果没有错误信号，没有完成信号，表示是<strong>无限数据流</strong></li>
</ul>
</li>
</ul>
</li>
<li><p>操作符</p>
<ul>
<li>对数据流进行一道道操作，成为操作符，比如工厂流水线<ul>
<li>map 元素映射为新元素</li>
<li>flatMap 元素映射为流，把每个元素转换流，把转换之后多个流合并大的流</li>
</ul>
</li>
</ul>
</li>
<li><p>SpringWebflux 执行流程和核心 API</p>
<ul>
<li><p>SpringWebflux 基于 Reactor，默认使用容器是 Netty，Netty 是高性能的 NIO 框架，异步非阻 塞的框架</p>
</li>
<li><p>SpringWebflux 执行过程和 SpringMVC 相似</p>
</li>
<li><p>SpringWebflux 里面 DispatcherHandler，负责请求的处理</p>
<ul>
<li>HandlerMapping：请求查询到处理的方法</li>
<li>HandlerAdapter：真正负责请求处理</li>
<li>HandlerResultHandler：响应结果处理</li>
</ul>
</li>
<li><p>SpringWebflux 实现函数式编程，两个接口：RouterFunction（路由处理）和 HandlerFunction（处理函数）</p>
</li>
<li><p>SpringWebflux 实现方式有两种</p>
<ul>
<li>注解编程模型</li>
<li>函数式编程模型</li>
</ul>
</li>
</ul>
</li>
<li><p>SpringWebflux（基于注解编程模型）</p>
</li>
<li><p>SpringWebflux（基于函数式编程模型）</p>
</li>
</ul>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="https://gitee.com/zcmmmm/zcmmmm">zcm</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://gitee.com/zcmmmm/zcmmmm/2022/09/23/Spring5%E6%A1%86%E6%9E%B6/">https://gitee.com/zcmmmm/zcmmmm/2022/09/23/Spring5%E6%A1%86%E6%9E%B6/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://gitee.com/zcmmmm/zcmmmm" target="_blank">无人深空</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/Spring/">Spring</a></div><div class="post_share"><div class="social-share" data-image="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/Spring/Spring.jpg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/2022/09/23/SpringMVC/"><img class="prev-cover" src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/Spring/Spring.jpg" onerror="onerror=null;src='/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">SpringMVC</div></div></a></div><div class="next-post pull-right"><a href="/2022/09/23/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"><img class="next-cover" src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/Design%20pattern.jpg" onerror="onerror=null;src='/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">设计模式</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/2022/10/23/Spring%E9%9D%A2%E7%BB%8F/" title="Spring面经"><img class="cover" src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/Spring/Spring.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-10-23</div><div class="title">Spring面经</div></div></a></div><div><a href="/2022/09/23/SpringMVC/" title="SpringMVC"><img class="cover" src="https://study-record-images.oss-cn-beijing.aliyuncs.com/Java/Spring/Spring.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-09-23</div><div class="title">SpringMVC</div></div></a></div></div></div></div><div class="aside-content" id="aside-content"><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content is-expand"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#Spring5-%E6%A1%86%E6%9E%B6"><span class="toc-text">Spring5 框架</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AF%BE%E7%A8%8B%E5%86%85%E5%AE%B9"><span class="toc-text">课程内容</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Spring5-%E6%A1%86%E6%9E%B6%E6%A6%82%E8%BF%B0"><span class="toc-text">Spring5 框架概述</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#IOC-%E5%AE%B9%E5%99%A8"><span class="toc-text">IOC 容器</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#AOP%EF%BC%88Aspect-Oriented-Programming%EF%BC%89%E9%9D%A2%E5%90%91%E5%88%87%E9%9D%A2%E7%BC%96%E7%A8%8B%EF%BC%88%E6%96%B9%E9%9D%A2%EF%BC%89"><span class="toc-text">AOP（Aspect Oriented Programming）面向切面编程（方面）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JdbcTemplate%EF%BC%88%E5%AF%B9-JDBC-%E7%9A%84%E5%B0%81%E8%A3%85%EF%BC%8C%E7%94%A8%E4%BA%8E%E6%93%8D%E4%BD%9C%E6%95%B0%E6%8D%AE%E5%BA%93%EF%BC%89"><span class="toc-text">JdbcTemplate（对 JDBC 的封装，用于操作数据库）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BA%8B%E5%8A%A1"><span class="toc-text">事务</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Spring5-%E6%A1%86%E6%9E%B6%E6%96%B0%E5%8A%9F%E8%83%BD"><span class="toc-text">Spring5 框架新功能</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Spring5-%E6%A1%86%E6%9E%B6%E6%96%B0%E5%8A%9F%E8%83%BD%EF%BC%88Webflux%EF%BC%89"><span class="toc-text">Spring5 框架新功能（Webflux）</span></a></li></ol></li></ol></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2022 - 2023 By zcm</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div></div></div><div id="search-mask"></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><script src="/js/search/local-search.js"></script><div class="js-pjax"></div><script src="/js/categories.js?v1"></script><script src="/js/navigation.js?v1"></script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div></body></html>